/*
 * @(#) SsmServiceImpl .java  1.0  2004-4-12
 *
 * Copyright 2003 by LongTop Corporation.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * LongTop Corporation ("Confidential Information").  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with LongTop.
 */
package com.cnc.ssm;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import com.cnc.bas.BasServiceImpl;
import com.cnc.bas.LTRuntimeException;
import com.cnc.bas.seq.ISeqService;
import com.cnc.bas.util.LTUtil;
import com.cnc.bas.util.MD5PasswordEncoder;
import com.cnc.bas.util.StringUtil;
import com.cnc.ssm.dao.ISsmDao;
import com.cnc.ssm.dao.ISsmSqlDao;
import com.cnc.ssm.model.PwCodeInfo;
import com.cnc.ssm.model.PwCodeType;
import com.cnc.ssm.model.PwEmployee;
import com.cnc.ssm.model.PwFunc;
import com.cnc.ssm.model.PwFuncRight;
import com.cnc.ssm.model.PwInst;
import com.cnc.ssm.model.PwLoginInfo;
import com.cnc.ssm.model.PwMenu;
import com.cnc.ssm.model.PwMenuRight;
import com.cnc.ssm.model.PwOper;
import com.cnc.ssm.model.PwOperRole;
import com.cnc.ssm.model.PwRole;
import com.cnc.ssm.model.PwSysConfig;

/**
 * User: Du bf Date: 2004-10-12
 */
public class SsmServiceImpl extends BasServiceImpl implements ISsmService {

	private ISsmDao ssmDao;

	private ISsmSqlDao ssmSqlDao;

	private ISeqService seqService;

	public ISsmDao getSsmDao() {
		return ssmDao;
	}

	public void setSsmDao(ISsmDao ssmDao) {
		this.ssmDao = ssmDao;
	}

	public ISsmSqlDao getSsmSqlDao() {
		return ssmSqlDao;
	}

	public void setSsmSqlDao(ISsmSqlDao ssmSqlDao) {
		this.ssmSqlDao = ssmSqlDao;
	}

	public ISeqService getSeqService() {
		return seqService;
	}

	public void setSeqService(ISeqService seqService) {
		this.seqService = seqService;
	}	
	
	public List listTaskDetail(String taskid) {
		return ssmSqlDao.listTaskDetail(taskid);
	}

	// liuwei更改
	public List listUserMenu(String userCode, String i18n) {
		return ssmSqlDao.listUserMenu(userCode, i18n);
	}

	public List listMenu(String menuCode) {
		return ssmDao.listMenu(menuCode);
	}

	public List listFunc(String menuCode) {
		return ssmDao.listFunc(menuCode);
	}

	public List listRole(String operCode) {
		return ssmSqlDao.listRole(operCode);
	}

	public List listOper(String rolecode) {
		return ssmSqlDao.listOper(rolecode);
	}

	public List listCodeType() {
		return ssmSqlDao.listCodeType();
	}

	public String getNameByCode(String codeType, String codeValue) {
		return ssmSqlDao.getNameByCode(codeType, codeValue);
	}

	public List listInst(String instType) {
		if (instType.equals("A"))
			return ssmDao.listAll(PwInst.class, "instLevel,instCode");
		else {
			PwInst inst = new PwInst();
			inst.setInstLevel(instType);
			return ssmDao.list(inst, "instCode");
		}
	}

	public List listInstTree() {
		return ssmSqlDao.listInstTree();
	}

	public PwInst loadInst(String instCode) {
		return (PwInst) ssmDao.load(PwInst.class, instCode);
	}

	public void addInst(PwInst inst) {
		String instCode = inst.getInstCode();
		if (ssmSqlDao.existInst(instCode))
			throw new LTRuntimeException("error.officecode.exist");
		ssmDao.add(inst);
	}

	public void updateInst(PwInst inst) {
		ssmDao.update(inst);
	}

	public void deleteInst(String instCode) {
		ssmDao.delete(PwInst.class, instCode);
	}

	public List listInst(String instCode, String instLevel) {
		return ssmSqlDao.listInst(instCode, instLevel);
	}

	public List listLoginLog(HashMap hs) {
		return ssmSqlDao.listLoginLog(hs);
	}

	public List listCodeType(HashMap hs) {
		return ssmSqlDao.listCodeType(hs);
	}

	public PwCodeType loadCodeType(String codeType) {
		return ssmDao.loadCodeType(codeType);
	}

	public void updateCodeType(PwCodeType vo) {
		ssmDao.update(vo);
	}

	public void deleteCodeType(String codeType) {
		PwCodeType vo = (PwCodeType) this.loadCodeType(codeType);
		ssmDao.delete(vo);
	}

	public void addCodeType(PwCodeType vo) {
		ssmDao.add(vo);
	}

	public List listCodeInfo(HashMap hs) {
		return ssmSqlDao.listCodeInfo(hs);
	}

	public List listCodeInfo(String codeType) {
		return ssmSqlDao.listCodeInfo(codeType);
	}

	//
	// public List listRegionInfo() {
	// List list = ssmDao.listAll(Region.class, "regionCode");
	// return list;
	// }

	public void deleteCodeInfo(long codeId) {
		ssmDao.delete(PwCodeInfo.class, new Long(codeId));
	}

	public void addCodeInfo(PwCodeInfo vo) {
		Long pk = this.seqService.getID("PW_CODE_INFO_ID");
		vo.setCodeId(pk);
		ssmDao.add(vo);
	}

	public PwCodeInfo loadCodeInfo(Long codeId) {
		return (PwCodeInfo) ssmDao.load(PwCodeInfo.class, codeId);
	}

	public void updateCodeInfo(PwCodeInfo vo) {
		ssmDao.update(vo);
	}

	public void addEmployee(PwEmployee vo) {
		String emplCode = vo.getEmplCode();
		if (ssmSqlDao.existEmployee(emplCode))
			throw new LTRuntimeException("error.emplcode.exist");
		ssmDao.add(vo);
	}

	public void updateEmployee(PwEmployee vo) {
		ssmDao.update(vo);
		ssmSqlDao.updateUserName(vo.getEmplCode(), vo.getEmplName());
	}

	public void deleteEmployee(String emplCode) {
		if (ssmSqlDao.existUser(emplCode))
			throw new LTRuntimeException("error.user.exist");
		ssmDao.delete(PwEmployee.class, emplCode);
	}

	public PwEmployee loadEmployee(String emplCode) {
		return (PwEmployee) ssmDao.load(PwEmployee.class, emplCode);
	}

	public List listEmployee(String keywords) {
		return ssmDao.listEmployee(keywords);
	}

	public List listEmployee(HashMap hs) {
		return ssmSqlDao.listEmployee(hs);
	}

	public List listSuperEmployee(String emplCode, String emplType) {
		return ssmSqlDao.listSuperEmployee(emplCode, emplType);
	}

	public boolean existEmployee(String emplCode) {
		return ssmSqlDao.existEmployee(emplCode);
	}

	public List listMenuTree() {
		return ssmSqlDao.listMenuTree();
	}

	public PwMenu loadMenu(String menuCode) {
		return (PwMenu) ssmDao.load(PwMenu.class, menuCode);
	}

	public void addMenu(PwMenu menu) {
		String menuCode = menu.getMenuCode();
		if (ssmSqlDao.existMenu(menuCode))
			throw new LTRuntimeException("error.menu.exist");
		ssmDao.add(menu);
	}

	public void updateMenu(PwMenu menu) {
		ssmDao.update(menu);
	}

	public void deleteMenu(String menuCode) {
		if (ssmSqlDao.existChildMenu(menuCode))
			throw new LTRuntimeException("error.menu.existchild");
		ssmDao.delete(PwMenu.class, menuCode);
	}

	public List listSysParam() {
		return ssmSqlDao.listSysParam();
	}

	public void addSysParam(String paramList) {
		if (paramList == null || paramList.equals(""))
			return;
		String[] arr1 = paramList.split("\r\n"); // enter key
		for (int i = 0; i < arr1.length; i++) {
			String[] arr2 = arr1[i].split("\t"); // tab key
			Long id = new Long(arr2[0].trim());
			String state = arr2[1].trim();
			if (state.equals("insert")) {
				_addSysParam(arr2[2], arr2[3], arr2[4]); // param_code,param_name,param_value
			} else if (state.equals("update")) {
				_updateSysParam(id, arr2[2], arr2[3], arr2[4]); // param_id,param_code,param_name,param_value
			} else if (state.equals("delete")) {
				_deleteSysParam(id);
			}
		}
	}

	public void updateFunc(String menuCode, String funcList) {
		if (funcList == null || funcList.equals(""))
			return;
		String[] arr1 = funcList.split("\r\n"); // enter key
		for (int i = 0; i < arr1.length; i++) {
			String[] arr2 = arr1[i].split("\t"); // tab key
			String funcCode = arr2[3].trim();
			String funcName = arr2[4].trim();
			String state = arr2[1].trim();
			if (state.equals("insert")) {
				_addFunc(menuCode, funcCode, funcName);
			} else if (state.equals("update")) {
				_updateFunc(menuCode, funcCode, funcName);
			} else if (state.equals("delete")) {
				_deleteFunc(funcCode);
			}
		}
	}

	public void addRole(PwRole vo) {
		String roleCode = vo.getRoleCode();
		if (ssmSqlDao.existRole(roleCode))
			throw new LTRuntimeException("error.rolecode.exist");
		this.ssmDao.add(vo);
	}

	public void updateRole(PwRole vo) {
		ssmDao.update(vo);
	}

	public void deleteRole(String roleCode) {
		ssmSqlDao.deleteFunctionAuth("R", roleCode);
		ssmSqlDao.deleteMenuAuth("R", roleCode);
		ssmSqlDao.deleteRole(roleCode);
		ssmDao.delete(PwRole.class, roleCode);
	}

	public PwRole loadRole(String roleCode) {
		return (PwRole) ssmDao.load(PwRole.class, roleCode);
	}

	public List listRole() {
		return ssmDao.list(PwRole.class, "roleCode");
	}

	public List listRole(PwRole casRole) {
		return ssmDao.list(casRole, "roleCode");
	}

	public void addOperator(PwOper pwOper) {
		String userCode = pwOper.getOperCode();
		if (ssmSqlDao.existUser(userCode))
			throw new LTRuntimeException("error.usercode.exist");
		ssmDao.add(pwOper);
	}

	public void updateOperator(PwOper basOper) {
		ssmDao.update(basOper);
	}

	public void deleteOperator(String operCode) {
		ssmSqlDao.deleteFunctionAuth("O", operCode);
		ssmSqlDao.deleteMenuAuth("O", operCode);
		ssmSqlDao.deleteOper(operCode);
		ssmDao.delete(PwOper.class, operCode);
	}

	public PwOper loadOperator(String operCode) {
		return (PwOper) ssmDao.load(PwOper.class, operCode);
	}

	public List listOperator(HashMap hs) {
		return ssmSqlDao.listOper(hs);
	}

	public boolean existUser(String userCode) {
		return ssmSqlDao.existUser(userCode);
	}

	public List listRole(HashMap hs) {
		return ssmSqlDao.listRole(hs);
	}

	public List listAuth(String refType, String refCode) {
		return ssmSqlDao.getAuthInfo(refType, refCode);
	}

	public void saveRoleOper(String type, String role, String oper) {
		String strList = "";
		if (type.equals("R")) // role
		{
			ssmSqlDao.deleteOper(role);
			strList = oper;
		} else { // operator
			ssmSqlDao.deleteRole(oper);
			strList = role;
		}

		if (strList.equals(""))
			return;

		StringTokenizer st = new StringTokenizer(strList, ",");
		while (st.hasMoreTokens()) {
			String code = st.nextToken();
			if (type.equals("R"))
				_saveRoleOperToDb(role, code);
			else
				_saveRoleOperToDb(code, oper);
		}
	}

	public void saveAuth(String refType, String refCode, String authlist) {
		if (refCode == null || refCode.equals(""))
			return;
		if (authlist == null || authlist.equals(""))
			return;
		ssmSqlDao.deleteMenuAuth(refType, refCode);
		ssmSqlDao.deleteFunctionAuth(refType, refCode);
		StringTokenizer st = new StringTokenizer(authlist, ",");
		int i = 0;
		String code = null;
		while (st.hasMoreTokens()) {
			String rightCode = st.nextToken();
			if (rightCode.length() > 1) {
				i = 0;
				code = rightCode;
				_saveMenuRight(refType, refCode, rightCode);
			} else {
				i++;
				if (rightCode.startsWith("~")) {
					continue;
				} else {
					_saveFunctionRight(refType, refCode, code + ":" + i);
				}
			}
		}
		return;
	}

	private void _saveFunctionRight(String refType, String refId,
			String rightCode) {
		PwFuncRight functionObj = new PwFuncRight();
		Long id = seqService.getID("PW_FUNC_RIGHT_ID");
		functionObj.setFuncRightId(id);
		functionObj.setRefType(refType);
		functionObj.setRefId(refId);
		functionObj.setFuncCode(rightCode);
		ssmDao.add(functionObj);
	}

	private void _saveMenuRight(String refType, String refId, String rightCode) {
		PwMenuRight menuObj = new PwMenuRight();
		Long id = seqService.getID("PW_MENU_RIGHT_ID");
		menuObj.setMenuRightId(id);
		menuObj.setRefType(refType);
		menuObj.setRefId(refId);
		menuObj.setMenuCode(rightCode);
		ssmDao.add(menuObj);
	}

	private void _saveRoleOperToDb(String roleCode, String operCode) {
		PwOperRole obj = new PwOperRole();
		Long id = seqService.getID("PW_ROLE_OPER_ID");
		obj.setOperRoleId(id);
		obj.setOperCode(operCode);
		obj.setRoleCode(roleCode);
		ssmDao.add(obj);
	}

	private void _addSysParam(String paramCode, String paramName,
			String paramValue) {
		PwSysConfig vo = new PwSysConfig();
		Long paramId = seqService.getID("PW_SYS_CONFIG_ID");
		vo.setParamId(paramId);
		vo.setParamCode(paramCode);
		vo.setParamName(paramName);
		vo.setParamValue(paramValue);
		ssmDao.add(vo);
	}

	private void _updateSysParam(Long paramId, String paramCode,
			String paramName, String paramValue) {
		PwSysConfig vo = new PwSysConfig();
		vo.setParamId(paramId);
		vo.setParamCode(paramCode);
		vo.setParamName(paramName);
		vo.setParamValue(paramValue);
		ssmDao.update(vo);
	}

	private void _deleteSysParam(Long paramId) {
		ssmDao.delete(PwSysConfig.class, paramId);
	}

	private void _addFunc(String menuCode, String funcCode, String funcName) {
		PwFunc vo = new PwFunc();
		vo.setFuncCode(funcCode);
		vo.setFuncName(funcName);
		vo.setMenuCode(menuCode);
		ssmDao.add(vo);
	}

	private void _updateFunc(String menuCode, String funcCode, String funcName) {
		PwFunc vo = new PwFunc();
		vo.setFuncCode(funcCode);
		vo.setFuncName(funcName);
		vo.setMenuCode(menuCode);
		ssmDao.update(vo);
	}

	private void _deleteFunc(String funcCode) {
		ssmDao.delete(PwFunc.class, funcCode);
	}

	public UserInfo login(String userName, String password)
			throws UserNotExistException, PasswordMismatchException,
			BlockedPasswordException, ExpiredPasswordException,
			UserLockedException {
		PwOper oper = ssmDao.getOperatorInfo(userName);
		if (oper == null) {
			throw new UserNotExistException(userName);
		} else if (!isMatch(oper, password)) {
			throw new PasswordMismatchException(userName);
		}
		if (oper.getOperStatus().equals("0")) {
			throw new UserLockedException(userName);
		}

		// if ((oper.getOpertype().equals("U")) ||
		// (oper.getOpertype().equals("M")) || (oper.getOpertype().equals("A")))
		{
			UserInfo operinfo = ssmSqlDao.getUserInfo(userName);
			if (operinfo == null)
				throw new UserNotExistException(userName);
			// if ((operinfo.getSuperEmplCode() != null) &&
			// (operinfo.getSuperEmplCode().equals("") == false)) {
			// PwEmployee employee = (PwEmployee) ssmDao.load(PwEmployee.class,
			// operinfo.getSuperEmplCode().trim());
			// if (employee != null)
			// operinfo.setSuperEmplName(employee.getEmplName());
			// }
			List permissionList = ssmSqlDao.getFuncPermission(userName);
			Iterator iter = permissionList.iterator();
			StringBuffer sb = new StringBuffer();
			while (iter.hasNext()) {
				sb.append(",");
				sb.append(iter.next().toString().trim());
			}
			operinfo.setUserPermission(sb.toString());
			operinfo.setLoginTime(new Date());

			operinfo = (UserInfo) LTUtil.trim(operinfo);
			return operinfo;
		}
		// return null;
	}

	private boolean isMatch(PwOper oper, String password) {
		if (oper == null || StringUtil.isEmpty(password)) {
			return false;
		}
		MD5PasswordEncoder encoder = new MD5PasswordEncoder();
		String encodePassword = encoder.encode(password);
		if (oper.getOperPwd().equals(encodePassword))
			return true;

		return false;
	}

	public void changePwd(HashMap hs) {
		String usercode = (String) hs.get("usercode");
		String oldpwd = (String) hs.get("oldpwd");
		if (oldpwd == null)
			oldpwd = "";
		String newpwd = (String) hs.get("newpwd");
		// 先验证旧密码输入是否有误
		MD5PasswordEncoder encoder = new MD5PasswordEncoder();
		oldpwd = encoder.encode(oldpwd);
		// String newpwd2 = (String) hs.get("newpwd2");
		PwOper oper = (PwOper) ssmDao.load(PwOper.class, usercode);
		if (oper.getOperPwd().equals(oldpwd) == false)
			throw new LTRuntimeException("bas.oldpwd.error");
		oper.setOperPwd(encoder.encode(newpwd));
		ssmDao.update(oper);
	}

	public Long addLoginInfo(UserInfo oper, String remoteAddr) {
		PwLoginInfo obj = new PwLoginInfo();
		Long id = seqService.getID("PW_LOGIN_INFO_ID");
		obj.setLoginId(id);
		// obj.setInstName(oper.getInstName());
		// obj.setInstCode(oper.getInstCode());
		obj.setOperCode(oper.getUserCode());
		obj.setOperName(oper.getUserName());
		obj.setLoginAddr(remoteAddr);
		obj.setLoginTime(new Date());
		ssmDao.add(obj);
		return id;
	}

	public void updateLoginInfo(Long loginId) {
		ssmSqlDao.updateLoginInfo(loginId);
	}
}
